home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 1992 August
/
info-mac-1992.iso
/
Language (lang)
/
Lazy-Scheme
/
Compilo
/
Comp
next >
Wrap
Text File
|
1990-09-21
|
26KB
|
737 lines
{••• Compilateur HELP-III •••}
(define (compile-expression exp f-env rbut cont mode)
(cond (constante? exp)
(compile-constant exp f-env rbut cont mode)
(variable? exp)
(compile-acces-variable exp f-env rbut cont mode)
(definition? exp)
(compile-definition exp f-env rbut cont mode)
(affectation? exp)
(compile-affectation exp f-env rbut cont mode)
(begin? exp)
(compile-begin exp f-env rbut cont mode)
(lambda? exp)
(compile-lambda exp f-env rbut cont mode)
(cond? exp)
(compile-cond exp f-env rbut cont mode)
(bindings? exp)
(compile-bindings exp f-env rbut cont mode)
(nomemo? exp)
(compile-nomemo exp f-env rbut cont mode)
(warn? exp)
(compile-warn exp f-env rbut cont mode)
(step-call? exp)
(compile-step exp f-env rbut cont mode)
(let? exp)
(compile-let exp f-env rbut cont mode)
(rec? exp)
(compile-rec exp f-env rbut cont mode)
(macro-exp? exp)
(compile-macro exp f-env rbut cont mode)
(ss-args? exp)
(compile-ss-args exp f-env rbut cont mode)
(application? exp)
(compile-application exp f-env rbut cont mode)
(error '?:syntx-er exp)))
(define (step? f e)
(not (or (number? f)
(constant? f)
(and (cons? f)(macro? (0 f))))))
(prinlength 1000)
(prindepth 1000)
(define (cg e)
(compile-expression e '() 'R0 'return default-mode))
(define (cu e)
(compile-expression e '? 'R0 'return default-mode))
;••• MODE •••
(define default-mode %000)
(define nomemo-mode %100)
(define step-mode %010)
(define warn-mode %001)
(define (+mode am mode)
(bitor! am (bcopy mode)))
(define (-mode am mode)
(bitand! (bitnot! (bcopy am))(bcopy mode)))
;••• CONTINUATION •••
(define (compile-cont cont)
(cond
(eq? cont 'next) (empty-pthunk)
(eq? cont 'return) (synt-rts)
(synt-bra cont)))
;••• CONSTANTES •••
(define (valeur k)
(eval k ()))
(define (every p l)
(cond (null? l) †
(p (0 l)) (every p (-1 l))))
(define (constante-simple? x)
(or (number? x)
(bitarray? x)
(cell? x)
(string? x)
(closure? x)
(environment? x)
(constant? x)
(quotee? x)))
(define (quotee? x)
(and (cons? x)
(eq? (0 x) 'quote)))
{(define (constante? x)
(or (constante-simple? x)
(and (cons? x) (every constante? x))))}
(define constante? constante-simple?)
(define (compile-constant k f-env rbut cont mode)
(add-source (append2pth (cond rbut (synt-move "L" (data (valeur k)) rbut)
(empty-pthunk))
(compile-cont cont))
(cons k f-env)))
;••• Define •••
(define (definition? x)
(and (cons? x)
(eq? (0 x) 'define)))
(define (compile-definition exp f-env rbut cont mode)
(let [(exp2 (vardef2def (-1 exp)))]
(add-source
(appendpths
(compile-expression (1 exp2) f-env 'r0 'next mode)
(compile-glob-write (0 exp2) rbut cont))
(cons exp f-env))))
(define (vardef2def exp)
(cond (ident? (0 exp)) exp
(constant? (0 exp)) exp
(cons? (0 exp)) (list (0 (0 exp)) (cons 'lambda (cons (-1 (0 exp)) (-1 exp))))
(error '?:syntx-er exp)))
;••• Variable •••
(define (variable? x)
(and (symbol? x)
(not (constant? x))))
;si l'environnemnt est non défini, l'accés aux variables sera non lexical
;sinon, optimisation et accès via adresses lexicales
;si la valeur n'a pas de but - on ne compile que la continuation
; TBD: ceci est il en accord avec la sémantique de Help-Unau (forçage=>effets de bords possibles) ?
(define (compile-acces-variable v f-env rbut cont mode)
(append2pth
(add-strict (getlex v f-env)) ;this is Help-Unau !!!
(cond rbut
(compile-av-opt v f-env rbut cont mode)
(compile-cont cont))))
(define (compile-av-opt v f-env rbut cont mode)
(let [(la (calcule-lex-address v f-env))]
(add-source (cond (error? la)(compile-lookup v rbut cont)
(null? la) (append2pth (compile-glob-lookup v rbut)
(compile-cont cont))
(append2pth (compile-lex-lookup la rbut)
(compile-cont cont)))
(cons v f-env))))
(define (compile-lookup v rbut cont)
(append2pth (synt-move "L" (data v) 'r0)
(cond (and (eq? rbut 'r0) (eq? cont 'return))
(synt-callo thunk:lookvarval)
(append2pth (synt-call thunk:lookvarval)
(synt-move "L" 'r0 rbut)))))
(define (compile-glob-lookup v rbut)
(append2pth (synt-move "L" (data v) 'r0)
(synt-move "L" '(4 r0) rbut)))
(define (compile-lex-lookup la rbut)
(cond (zero? (0 la)) (synt-move "L" `(,(+ 8 (* 4 (-1 la))) r2) rbut)
(appendpths (synt-move "L" '(4 r2) 'a1)
(compile-frame-offset (1- (0 la)))
(synt-move "L" `(,(+ 8 (* 4 (-1 la))) a1) rbut))))
(define (compile-frame-offset fo)
(cond (zero? fo) (empty-pthunk)
(append2pth (synt-move "L" '(4 A1) 'A1)
(compile-frame-offset (1- fo)))))
(define (comp-force rf)
(let [(laf (cree-label "after-hold"))]
(appendpths (synt-btst 2 `(-4 ,rf))
(synt-beq laf)
(cond (eq? rf 'r0)(synt-call thunk:holdr0)
(eq? rf 'a0)(synt-call thunk:holda0)
(eq? rf 'a1)(synt-call thunk:holda1)
(appendpths (synt-move "L" rf 'R0)
(synt-call thunk:holdr0)
(synt-move "L" 'r0 rf)))
(synt-label laf))))
;••• affectation •••
(define (affectation? exp)
(and (cons? exp) (eq? (0 exp) '=!)))
(define (compile-affectation exp f-env rbut cont mode)
(let [(la (calcule-lex-address (1 exp) f-env))
(t (compile-expression (2 exp) f-env 'r0 'next mode))]
(add-source
(append2pth
t
(cond (error? la)(compile-write (1 exp) rbut cont)
(null? la) (compile-glob-write (1 exp) rbut cont)
(compile-lex-write la) rbut cont))
(cons exp f-env))))
(define (compile-write v rbut cont)
(append2pth (synt-move "L" (data v) 'a0)
(cond (and (eq? cont 'return)(eq? rbut 'r0))
(synt-callo thunk:valvarset)
(appendpths (synt-call thunk:valvarset)
(synt-move "L" 'r0 rbut)
(compile-cont cont)))))
(define (compile-glob-write v rbut cont)
(appendpths (synt-move "L" (data v) 'a1)
(synt-move "L" 'r0 '(4 a1))
(synt-move "L" 'r0 rbut)
(compile-cont cont)))
(define (compile-lex-write la rbut cont)
(cond (zero? (0 la)) (synt-move "L" 'r0 `(,(+ 8 (* 4 (-1 la))) r2))
(appendpths (synt-move "L" '(4 r2) 'a1)
(compile-frame-offset (1- (0 la)))
(synt-move "L" 'r0 `(,(+ 8 (* 4 (-1 la))) a1))
(synt-move "L" 'r0 rbut)
(compile-cont cont))))
;••• begin •••
(define (begin? exp)
(and (cons? exp) (eq? (0 exp) 'begin)))
(define (compile-begin exp f-env rbut cont mode)
(add-source (comp-begin (-1 exp) f-env rbut cont mode)
(cons exp f-env)))
(define (comp-begin exps f-env rbut cont mode)
(cond (null? exps) (compile-constant '? f-env rbut cont mode)
(null? (-1 exps)) (compile-expression (0 exps) f-env rbut cont mode)
(let [(t (compile-expression (0 exps) f-env ƒ 'next mode))]
(cond (memq? 'm (mod t))
(preservepth 'r2
t
(comp-begin (-1 exps) f-env rbut cont mode))
(comp-begin (-1 exps) f-env rbut cont mode)))))
;••• Lambda •••
(define (lambda? exp)
(and (cons? exp) (eq? (0 exp) 'lambda)))
(define (compile-lambda exp f-env rbut cont mode)
(cond rbut
(let [(f-env (etend-env f-env (1 exp)))]
(add-source (appendpths (compile-closure-make (1 exp) (compile-corps (-1 exp) f-env) f-env)
(synt-move "L" 'a0 rbut)
(compile-cont cont))
exp))
(compile-cont cont)))
(define (compile-corps exp f-env)
(let [(t (comp-begin (-1 exp) f-env 'R0 'return default-mode))]
(add-source (append2pth (compile-make-env (0 exp) t) t) (-1 exp))))
(define (compile-make-env l t)
(let [(at (clos-typar l 0))]
(cond (zero? (-1 at))
(cond (zero? (0 at)) (empty-pthunk)
(appendpths
(cond (memq? 'e (nec t))
(appendpths
(synt-move "L" `(# ,(+ 3 (* 2 (0 at)))) 'd0)
(synt-call thunk:getablock)
(synt-move "B" `(# ,type:env) '(-3 a0)))
(appendpths
(synt-move "L" `(# ,(+ 3 (0 at))) 'd0)
(synt-call thunk:getablock)
(synt-move "B" `(# ,type:senv) '(-3 a0))))
(synt-move "L" 'R2 '(4 a0))
(synt-move "L" 'a0 'r2)
(synt-lea '(8 a0) 'a0)
(compile-pop l (memq? 'e (nec t)) (0 at))))
(appendpths
(compile-cons-extra (0 at))
(cond (memq? 'e (nec t))
(appendpths
(synt-move "L" `(# ,(+ 5 (* 2 (0 at)))) 'd0)
(synt-call thunk:getablock)
(synt-move "B" `(# ,type:env) '(-3 a0)))
(appendpths
(synt-move "L" `(# ,(+ 4 (0 at))) 'd0)
(synt-call thunk:getablock)
(synt-move "B" `(# ,type:senv) '(-3 a0))))
(synt-move "L" 'R2 '(4 a0))
(synt-move "L" 'a0 'r2)
(synt-lea '(8 a0) 'a0)
(compile-pop l (memq? 'e (nec t))(1+ (0 at)))))))
(define (compile-pop l f n)
(appendpths (compile-pops n)
(cond f
(compile-fill (reverse l))
(empty-thunk))
(synt-lea '(-4 LP) 'LP)))
(define (compile-pops n)
(cond (zero? n) (empty-pthunk)
(append2pth (synt-move "L" '(- LP) '(a0 +))
(compile-pops (1- n)))))
(define (compile-fill l)
(cond (null? l) (empty-pthunk)
(append2pth (synt-move "L" (data (0 l)) '(a0 +))
(compile-fill (-1 l)))))
(define (compile-closure-make l t f-env)
(appendpths (synt-move "L" `(# 4) 'D0)
(synt-call thunk:getablock)
(synt-move "B" `(# ,(type type)) '(-3 a0))
(synt-move "L" 'r2 '(4 a0))
(synt-move "L" (data t) '(a0))
(synt-move "L" `(# ,(+ (arite l)(* 65536 (tobit f-env l (str t))))) '(8 a0))))
(define (tobit f-env l s)
(letrec [((loop s b)
(cond (null? s) b
(eq? (-1 (0 s)) f-env) (loop (-1 s) (findvar (0(0 s)) l 1))
(loop (-1 l) b)))
((findvar v l n)
(cond (null? l) 0
(eq? (0 l) v) n
(findvar v (-1 l) (+ n n))))]
(loop s 0)))
(define (compile-cons-extra ar)
(let [(loop (cree-label "loop"))
(after-loop (cree-label "after-loop"))]
(appendpths (synt-move "L" (data ()) 'r0)
(synt-sub "W" `(# ,ar) 'd1)
(synt-move "W" 'd1 '(- sp))
(synt-beq after-loop)
(synt-label loop)
(synt-move "L" '(# 3) 'd0)
(synt-call thunk:getablock)
(synt-move "L" 'r0 '(4 a0))
(synt-move "L" 'a0 'r0)
(synt-move "L" '(- lp) '(r0))
(synt-sub "W" '(# 1) '(sp))
(synt-bpl loop)
(synt-label after-loop)
(synt-lea '(4 SP) 'Sp)
(synt-move "L" 'r0 '(LP +)))))
(define (arite l)
(let [(at (clos-typar l 0))]
(coerce (bitor! (coerce (0 at) 3)
(coerce (* 256 (-1 at)) 3)) 1)))
(define (clos-typar c a)
(cond (null? c) (cons a 0)
(ident? c) (cons a 1)
(and (cons? c)(ident? (0 c))) (clos-typar (-1 c) (1+ a))
(error '?:syntx-er c)))
;••• Cond •••
;même si en Help, cond p.e vu comme une closure, on le compile ici (rapidité)
(define (cond? exp)
(and (cons? exp) (eq? (0 exp) 'cond)))
(define (compile-cond exp f-env rbut cont mode)
(cond (eq? cont 'next)
(let [(fin (cree-label "apres-cond"))]
(append2pth (compile-clauses (-1 exp) f-env rbut fin mode)
(synt-label fin)))
(compile-clauses (-1 exp) f-env rbut cont mode)))
(define (compile-clauses exp f-env rbut cont mode)
(cond (null? exp) (compile-constant ƒ f-env rbut cont mode)
(null? (-1 exp)) (appendpths (compile-expression (0 exp) f-env 'r0 'next mode)
(comp-force 'r0)
(synt-move "L" 'r0 rbut)
(compile-cont cont))
(compile-clause
(0 exp)
(1 exp)
(-2 exp)
{(cree-label "cond-undef")}
f-env
rbut
cont
mode)))
(define (compile-clause test action others f-env rbut cont mode)
(cond (constante? test)
(cond (true? test)
(compile-expression action f-env rbut cont mode)
(compile-clauses others f-env rbut cont mode))
(let [(t-act (compile-expression action f-env rbut cont mode))
(t-tst (append2pth (compile-expression test f-env 'r0 'next mode)
(comp-force 'r0)))
(t-oth (compile-clauses others f-env rbut cont mode))
(l-fls (cree-label "cond-faux"))]
(preservepth 'r2
t-tst
(append2pth (compile-test "L" 'r0 (data ƒ) l-fls)
(undes2pth (append2pth t-act (synt-label l-fls))
t-oth))))))
(define (true? exp)
(neq? (valeur exp) ƒ))
(define (compile-test s m1 m2 l)
(append2pth (synt-cmp s m1 m2)
(synt-beq l)))
;••• bindings •••
(define (bindings? exp)
(cond (cons? exp) (eq? (0 exp) 'bindings)))
(define (compile-bindings exp f-env rbut cont mode)
(add-source
(cond rbut
(appendpths (synt-move "L" 'r2 rbut)
(add-info '(e)()())
(compile-cont cont))
(compile-cont cont))
(cons exp f-env)))
;••• Macros •••
(define (macro-exp? exp)
(cond (cons? exp) (macro? (0 exp))))
(define (compile-macro exp f-env rbut cont mode)
(add-source (compile-expression (expand exp) f-env rbut cont mode) (cons exp f-env)))
;••• NoMemo •••
(define (nomemo? exp)
(and (cons? exp) (eq? (0 exp) 'nomemo)))
(define (compile-nomemo exp f-env rbut cont mode)
(add-source
(cond (constante? exp)(compile-constant exp f-env rbut cont mode)
(quotee? exp)(compile-quotee exp f-env rbut cont mode)
(let [(t (compile-expression (cons 'begin (-1 exp)) f-env rbut cont mode))]
(appendpths (synt-move "L" 'D7 '(- sp))
(synt-bset 31 'D7)
(compile-susp t rbut cont)
(synt-move "L" '(sp +) 'D7)))) (cons exp f-env)))
;••• warn •••
(define (warn? exp)
(and (cons? exp) (eq? (0 exp) 'warn)))
(define (compile-warn exp f-env rbut cont mode)
(add-source
(appendpths (synt-move "L" 'D7 '(- sp))
(synt-move "B" (cond (eq? (1 exp) ƒ) '(# 0)
(eq? (1 exp) ()) '(# -1)
'(# 1)) 'D7)
(compile-expression (cons 'begin (-1 exp)) f-env rbut cont mode)
(synt-move "L" '(sp +) 'd7)) (cons exp f-env)))
;••• Step •••
(define (step-call? exp)
(and (cons? exp) (eq? (0 exp) 'step)))
(define (compile-step exp f-env rbut cont mode)
)
;••• let •••
(define (let? exp)
(and (cons? exp) (eq? (0 exp) 'let)))
(define (compile-let exp f-env rbut cont mode)
)
;••• Letrec •••
(define (rec? exp)
(and (cons? exp) (eq? (0 exp) 'letrec)))
(define (compile-rec exp f-env rbut cont mode)
)
;••• Application sans args •••
(define (ss-args? exp)
(and (cons? exp) (null? (-1 exp))))
(define (compile-ss-args exp f-env rbut cont mode)
(add-source
(cond {(lambda? (0 exp)) (compile-let (lambda2let exp) f-env rbut cont mode)}
(constante? (0 exp)) (compile-opt-ss-args (valeur (0 exp)) f-env rbut cont mode)
(quotee? (0 exp)) (compile-opt-ss-args (1 (0 exp)) f-env rbut cont mode)
(compile-noopt-ss-arg exp f-env rbut cont mode))
exp))
(define (compile-noopt-ss-arg exp f-env rbut cont mode)
(appendpths (compile-expression (0 exp) f-env 'r0 'next mode)
(synt-move "L" 'r0 '(LP +))
(synt-move "L" 'lp '(- SP))
(synt-move "W" '(# 0) 'd1)
(cond (and (eq? cont 'return)(eq? rbut 'r0))
(synt-callo thunk:applyit)
(appendpths (synt-call thunk:applyit)
(synt-move "L" 'r0 rbut)
(compile-cont cont)))))
(define (compile-opt-ss-args f f-env rbut cont mode)
(cond (=? (type f) 1) (error '?:few-args f)
(closure? f) (letrec [(at (getaritype f))
(type (modulo at 256))
(ari (/ at 256))]
(cond (<>? ari 0) (error '?:few-args f)
(=? type 0) (compile-procn-call-ss f cont rbut)
(compile-nproc-call-ss f cont rbut)))
(error '? (list "ne sais pas compiler1" f))))
(define (compile-procn-call-ss f cont rbut)
(appendpths (synt-move "L" (data f) 'a0)
(synt-move "L" 'a0 '(LP +))
(synt-move "L" '(4 a0) 'r2)
(synt-move "L" '(a0) 'a0)
(cond (and (eq? cont 'return)
(eq? rbut 'r0)) (synt-jmp '(8 a0))
(appendpths (synt-jsr '(8 a0))
(synt-move "L" 'r0 rbut)
(compile-cont cont)))))
(define (compile-nproc-call-ss f cont rbut)
(appendpths (synt-move "L" (data f) 'a0)
(synt-move "L" 'a0 '(LP +))
(synt-move "L" (data '()) '(LP +))
(synt-move "W" '(# 0) 'd1)
(synt-move "L" '(4 a0) 'r2)
(synt-move "L" '(a0) 'a0)
(cond (and (eq? cont 'return)
(eq? rbut 'r0)) (synt-jmp '(8 a0))
(appendpths (synt-jsr '(8 a0))
(synt-move "L" 'r0 rbut)
(compile-cont cont)))))
;••• Application avec args •••
(define (application? exp)
(cons? exp))
(define (compile-application exp f-env rbut cont mode)
(add-source
(cond {(lambda? (0 exp)) (compile-let (lambda2let exp) f-env rbut cont mode)}
(constante? (0 exp)) (compile-opt-app (valeur (0 exp)) (-1 exp) f-env rbut cont mode)
(quotee? (0 exp)) (compile-opt-app (1 (0 exp))(-1 exp) f-env rbut cont mode)
(compile-noopt-app exp f-env rbut cont mode))
exp))
(define (compile-noopt-app exp f-env rbut cont mode)
(append2pth
(preservepth 'r2
(compile-expression (0 exp) f-env 'r0 'next mode)
(appendpths (synt-move "L" 'r0 '(LP +))
(synt-move "L" 'LP '(- SP))
(push-thunks (-1 exp) f-env mode)
(synt-move "W" (list '# (length (-1 exp))) 'd1)))
(cond (and (eq? cont 'return)(eq? rbut 'r0))
(synt-callo thunk:susp&apply)
(appendpths (synt-call thunk:susp&apply)
(synt-move "L" 'r0 rbut)
(compile-cont cont)))))
(define (push-thunks args f-env mode)
(cond (null? args) (empty-pthunk)
(append2pth (synt-move "L"
(data (compile-expression (0 args) f-env 'r0 'return mode))
'(LP +))
(push-thunks (-1 args) f-env mode))))
(define (compile-opt-app f arg f-env rbut cont mode)
(cond (=? (type f) 1) (compile-select f arg f-env rbut cont mode)
(closure? f) (compile-clos-app f arg f-env rbut cont mode)
(error '? (list "sais pas compiler2" (cons f arg)))))
(define (compile-select f arg f-env rbut cont mode)
(error '? (list "sais pas compiler2" (cons f arg))))
(define (compile-clos-app f arg f-env rbut cont mode)
(letrec [(at (getaritype f))
(type (modulo at 256))
(ari (/ at 256))
(narg (length arg))]
(cond (=? type 0) (cond (=? narg ari) (compile-procn-call f arg cont rbut f-env mode)
(>? narg ari) (error '?:too-args (cons f arg))
(<? narg ari) (error '?:few-args (cons f arg)))
(>? narg ari)(compile-nproc-call f arg cont rbut f-env mode)
(=? narg ari)(compile-nproc-call f arg cont rbut f-env mode)
(error? '?:few-args (cons f arg)))))
(define (compile-procn-call f args cont rbut f-env mode)
(appendpths (synt-move "L" (data f) '(lp +))
(push-args2 (getstrict f) args f-env mode)
(synt-move "L" (data f) 'a0)
(synt-move "L" '(4 a0) 'r2)
(synt-move "L" '(a0) 'a0)
(cond (and (eq? cont 'return)
(eq? rbut 'r0)) (synt-jmp '(8 a0))
(appendpths (synt-jsr '(8 a0))
(synt-move "L" 'r0 rbut)
(compile-cont cont)))))
(define (push-args2 s args f-env mode)
(letrec [((loop s arg n)
(cond (null? arg)
(empty-pthunk)
(n s)
(preservepth 'r2
(compile-expression (0 arg) f-env '(lp +) 'next mode)
(append2pth
(cond (variable? (0 arg))
(add-strict (getlex (0 arg) f-env))
(empty-pthunk))
(loop s (-1 arg) (cond (=? n 15) 15 (1+ n)))))
(appendpths (compile-chilled (0 arg) f-env '(lp +) 'next mode)
(loop s (-1 arg) (cond (=? n 15) 15 (1+ n))))))]
(loop s args 0)))
(define (compile-nproc-call f args cont rbut f-env mode)
(appendpths (synt-move "L" (data f) '(lp +))
(push-args2 (getstrict f) args f-env mode)
(synt-move "L" (data f) 'a0)
(synt-move "L" '(4 a0) 'r2)
(synt-move "L" '(a0) 'a0)
(synt-move "W" `(# ,(length args)) 'd1)
(cond (and (eq? cont 'return)
(eq? rbut 'r0)) (synt-jmp '(8 a0))
(appendpths (synt-jsr '(8 a0))
(synt-move "L" 'r0 rbut)
(compile-cont cont)))))
;••• Paresse •••
(define (compile-chilled exp f-env rbut cont mode)
(cond (constante? exp)(compile-constant exp f-env rbut cont mode)
(quotee? exp)(compile-quotee exp f-env rbut cont mode)
(let [(t (compile-expression exp f-env rbut 'return mode))]
(compile-susp t rbut cont))))
(define (compile-susp t rbut cont)
(appendpths (synt-move "L" '(# 4) 'd0)
(synt-call thunk:getablock)
(synt-move "W" `(# ,(+ 1024 type:susp)) '(-4 a0))
(synt-move "L" (data t) '(a0))
(synt-move "L" 'r2 '(4 a0))
(synt-move "L" 'D7 '(8 a0))
(synt-move "L" 'a0 rbut)
(compile-cont cont)))
;••• labels •••
;un label sera le cons de 'label et de la chaîne
;c'est l'adresse du cons formé qui indiquera le label
(define (cree-label s)
(cons 'label s))
;••• Xrefs •••
;on peut xrefer une donnée (data)
(define (data o)
(list 'data o))
(define (data? u)
(and (cons? u)
(eq? (0 u) 'data)))
;••• TYPES •••
(define type:env 16)
(define type:senv 17)
(define type:susp 20)
;••• Divers •••
(define (union-set e f)
(cond (null? e) f
(memq? (0 e) f)(union-set (-1 e) f)
(cons (0 e) (union-set (-1 e) f))))
(define (union-tout l)
(cond (null? l) ()
(union-set (0 l) (union-tout (-1 l)))))
(define (differ-set e f)
(cond (null? e) '()
(memq? (0 e) f)(differ-set (-1 e) f)
(cons (0 e) (differ-set (-1 e) f))))
(define (inter-set e f)
(cond (null? e) '()
(memq? (0 e) f)(cons e (inter-set (-1 e) f))
(inter-set (-1 e) f)))
;••• Environnements •••
;nous représenterons le "futur env" par une cellule
;1er élém:next frame ou () ou ?
;suite:les variables
(define (etend-env env lv)
(apply cell (cons env (reverse lv))))
;••• calcule le Frame Offset et le Var Offset…dans l'environnement futur •••
(define (calcule-lex-address var f-env)
(CalcLex var f-env 0 0))
(define (CalcLex var f-env fo vo)
(cond (null? f-env) ()
(eq? f-env '?) '?
(=? (blength f-env) (+ 2 vo)) (CalcLex var (0 f-env) (1+ fo) 0)
(eq? ((1+ vo) f-env) var) (cons fo vo)
(CalcLex var f-env fo (1+ vo))))
(define (getlex var f-env)
(letrec [((getenv f-env vo)
(cond (null? f-env) ()
(eq? f-env '?) '?
(=? (blength f-env) (+ 2 vo)) (getenv (0 f-env) 0)
(eq? ((1+ vo) f-env) var) f-env
(getenv f-env (1+ vo))))]
(cons var (getenv f-env 0))))